
/*---------------------------------------------------------------------------

  FILENAME:
        serial.c

  PURPOSE:
	Provide serial operation.

  REVISION HISTORY:
        Date            Engineer        Revision        Remarks
	16/02/2009	Vincent. Young	1.2	

  NOTES:


  LICENSE:
        Copyright (c) 2009, Vincent Young (vincentgodyoung@hotmail.com)

        This source code is released for free distribution under the terms
        of the GNU General Public License.

----------------------------------------------------------------------------*/

// ���ڲ����ķ�װ
// ���ģʽ��pcģʽ��moxaģʽ�����뿪����server.h��

// local project include files
#include "serial.h"

// system library include files
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <string.h>

#if MOXAMODE
#include <moxadevice.h>
#endif

int serial;

int speed_arr[13] = {
	B921600, B460800, B230400, B115200, B57600, 
	B38400, B19200, B9600, B4800, B2400, B1200, B300, B110
};
int name_arr[13] = {
	921600, 460800, 230400, 115200, 57600, 
	38400, 19200, 9600, 4800, 2400, 1200, 300, 110
};
int socketid;

int SerialOpen(char * portname, int speed)
{
	int ret;
	int i;
#if MOXAMODE
	int mode = 0;
#endif
	struct termios ioset;
	serial = open(portname, O_RDWR | O_NOCTTY | O_NDELAY);
	if ( serial == -1 )
	{
		printf("serialopen: open serial port [%s] error [%s]\n", portname, strerror(errno));
		return -1;
	}
	
#if MOXAMODE
	// set moxa work mode
	printf("running with moxa_set_op_mode\n");
	ret = ioctl(serial, MOXA_SET_OP_MODE, &mode);
	// ����moxa�豸�Ĵ���Ϊrs232����ģʽ
#endif

	ioset.c_iflag = 0;
	ioset.c_oflag = 0;
	ioset.c_lflag = 0;
	ioset.c_cflag |= CLOCAL;
	ioset.c_cflag |= CREAD;
	ioset.c_cflag |= CS8;
	ioset.c_cc[VTIME] = 0;
	ioset.c_cc[VMIN] = 0;

	// set speed
	for (i = 0; i < sizeof(speed_arr)/sizeof(int); i++)
	{
		if (speed == name_arr[i])
		{
			ioset.c_cflag |= speed_arr[i];
		}
	}
	
	tcflush(serial, TCIOFLUSH);		
	ret = tcsetattr(serial, TCSANOW, &ioset);
	if (ret != 0)
	{
		printf("serialopen: set speed failed\n");
		return -2;
	}
	tcflush(serial, TCIOFLUSH);
#if	LOGREGMODE
	printf("serialopen: serial port [%s] with speed[%d] open succed \n", 
			portname, speed);
#endif
	return 0;
}

int SerialWrite(char *buf, int len)
{
	int sendlen;
#if VP2
	if(len >= 2)
	{
		if ((buf[len-2]=='\x0d')&&(buf[len-1]=='\x0a'))
		{
			buf[len-2] = '\x0a';
			len = len - 1;
		}
	}
#endif
#if LOGREGMODE
	printf("serialwrite: ready to send to serial[%d] buf[%s] len[%d]\n", serial, buf, len);
#endif
	sendlen = write(serial, buf, len);
	if (sendlen < 0)
	{
		printf("serialwrite: [%s] to serial error [%s]\n", buf, strerror(errno));
		return -1;
	}
	tcflush(serial, TCIOFLUSH);
#if	LOGREGMODE
	printf("serialwrite: wrote to serial [%s] sendlen [%d]\n", buf, sendlen);
#endif
	return sendlen;
}

int SerialNonBlockRead(char *buf, int size)
{
	int readlen;
	memset(buf, '\0', size);
	readlen = read(serial, buf, size);
#if	LOGREGMODE
	if (readlen > 0)
		printf("serialnonblockread: read from serial [%s] \n", buf);
#endif
	if (readlen < 0)
	{
		printf("serialnonblockread: read error [%s]\n", strerror(errno));
		return -2;
	}
#if	LOGREGMODE
	if (readlen > 0)
	printf("serialnonblockread: read from serial [%s] \n", buf);
#endif
	return readlen;
}

